﻿using DataAcquisitionDAL;
using DataAcquisitionBLL;
using WinFormium;
using WinFormium.Forms;
using Newtonsoft.Json;
namespace DataAcquisition
{
    internal class IndexFormium: Formium
    {
        #region 属性

        /// <summary>
        /// 逻辑
        /// </summary>
        private DataAcquisitionBLL.Index Service = new DataAcquisitionBLL.Index();

        /// <summary>
        /// 试压记录
        /// </summary>
        private TestRecordModel TestRecordModelService = new TestRecordModel();

        /// <summary>
        /// 数据库状态
        /// </summary>
        private bool DataBaseState = false;

        /// <summary>
        /// 开始采集状态
        /// </summary>
        private bool StartState = false;

        /// <summary>
        /// 播报
        /// </summary>
        private BroadcastServices Broad = new BroadcastServices();

        /// <summary>工程
        /// 
        /// </summary>
        public ProjectItem? ProjectItemService;

        /// <summary>
        /// 试压模板
        /// </summary>
        private TemplateModel? TemplateModelService;

        #region 采集计时器
        /// <summary>总计时器
        /// 
        /// </summary>
        private System.Timers.Timer TotalTimer = new System.Timers.Timer();

        /// <summary>近端计时器
        /// 
        /// </summary>
        private System.Timers.Timer MainCollectTimer = new System.Timers.Timer();

        /// <summary>远端计时器
        /// 
        /// </summary>
        private System.Timers.Timer RemoteCollectTimer = new System.Timers.Timer();

        /// <summary>播报错误计时器
        /// 
        /// </summary>
        private System.Timers.Timer BroadErrorTimer = new System.Timers.Timer();

        #endregion
        /// <summary>
        /// 总时间
        /// </summary>
        private long TotalTime = 0;

        //开始时间
        private DateTime StartTime;

        //结束时间
        private DateTime EndTime;

        #region 近端数据

        /// <summary>主风扇
        /// 
        /// </summary>
        private bool MainFanState;

        /// <summary>主压力
        /// 
        /// </summary>
        private double MainPressure = 0;

        /// <summary>主机箱温度
        /// 
        /// </summary>
        private double MainMachineTemplature = 0;

        /// <summary>主环境温度
        /// 
        /// </summary>
        private double MainEnviromentTemplature = 0;

        /// <summary>主介质温度
        /// 
        /// </summary>
        private double MainMediumTemplature = 0;

        /// <summary> 近端压力错误
        /// 
        /// </summary>
        private bool MainPressureError;

        /// <summary> 近端温度错误
        /// 
        /// </summary>
        private bool MainTemplatureError;

        #endregion

        #region 远端数据
        /// <summary>远端风扇
        /// 
        /// </summary>
        private bool RemoteFanState;

        /// <summary>远端压力
        /// 
        /// </summary>
        private double RemotePressure = 0;

        /// <summary>远端机温度
        /// 
        /// </summary>
        private double RemoteMachineTemplature = 0;

        /// <summary>远端环境温度
        /// 
        /// </summary>
        private double RemoteEnviromentTemplature = 0;

        /// <summary>远端介质温度
        /// 
        /// </summary>
        private double RemoteMediumTemplature = 0;

        /// <summary> 远端压力错误
        /// 
        /// </summary>
        private bool RemotePressureError;

        /// <summary> 远端温度错误
        /// 
        /// </summary>
        private bool RemoteTemplatureError;

        #endregion

        #region 阶段数据

        string CurrentStage = string.Empty;

        /// <summary>阶段
        /// 
        /// </summary>
        List<string> StageList = new List<string>();

        /// <summary> 起步阶段压力
        /// 
        /// </summary>
        double StartStagePressure;

        /// <summary> 起步阶段压力上限
        /// 
        /// </summary>
        double StartStagePressureMax = 0;

        /// <summary> 起步阶段压力下限
        /// 
        /// </summary>
        double StartStagePressureMin = 0;

        /// <summary> 保持阶段压力
        /// 
        /// </summary>
        double HoldingStagePressure;

        /// <summary> 保持阶段压力上限
        /// 
        /// </summary>
        double HoldingStagePressureMax = 0;

        /// <summary> 保持阶段压力下限
        /// 
        /// </summary>
        double HoldingStagePressureMin = 0;

        /// <summary>
        /// 允许保持阶段
        /// </summary>
        bool EnableHoldingStage = false;

        /// <summary>
        /// 当前阶段试压结果
        /// </summary>
        bool StageResult = false;

        /// <summary>
        /// 当前阶段总时间
        /// </summary>
        long StageTotalTime = 0;

        /// <summary>起步阶段总时间
        /// 单位s
        /// </summary>
        int StartStageTimeInterval = 20;

        /// <summary>当前步阶段剩余时间
        /// 单位s
        /// </summary>
        int StartStageTime = 20;

        /// <summary>
        /// 开始起步稳压
        /// </summary>
        bool StartStageHolding = false;

        /// <summary>
        /// 采集点列表
        /// </summary>
        private List<double> PointList = new List<double>();

        /// <summary> 当前阶段计时器
        /// 
        /// </summary>
        private System.Timers.Timer StageTimer;

        /// <summary> 起步计时器
        /// 
        /// </summary>
        private System.Timers.Timer StartStageTimer;

        /// <summary> 保持阶段计时器
        /// 
        /// </summary>
        private System.Timers.Timer HoldingStageTimer;

        /// <summary>
        /// 剩余时间
        /// </summary>
        private string SurplusTotalTimeString = string.Empty;

        /// <summary> 保持阶段错误次数
        /// 
        /// </summary>
        int HoldStageErrorTimes = 0;

        #endregion

        #endregion

        #region 自定义方法

        #region 消息
        /// <summary> 前端Loading消息
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void LayerLoading(string msg)
        {
            string js = string.Format("layerLoading('{0}')", msg);
            EvaluateJavaScript(js);
        }

        /// <summary> 关闭前端Loading消息
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void LayerLoadingClose()
        {
            string js = string.Format("endLayerLoading()");
            EvaluateJavaScript(js);
        }

        /// <summary> 前端Error消息
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void LayerError(string msg)
        {
            LayerMsg(msg, 2);
        }

        /// <summary> 前端Success消息
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void LayerSuccess(string msg)
        {
            LayerMsg(msg, 1);
        }

        /// <summary>前端消息
        /// 
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="icon"></param>
        private void LayerMsg(string msg, int icon)
        {
            string js = string.Format("layerMessage('{0}','{1}')", msg, icon);
            EvaluateJavaScript(js);
        }
        #endregion
        private void EvaluateJavaScript(string js)
        {
            if (js is not null)
            {
                try
                {
                    EvaluateJavaScriptAsync(js);
                }
                catch (Exception)
                {
                }
            }
        }

        /// <summary>
        /// 注册方法
        /// </summary>
        private void RegisterJavaScriptMessagHandler()
        {

            RegisterJavaScriptMessagHandler("ShowForm", args =>
            {
                bool res = CheckDataBaseState();
                if (!res)
                {
                    return;
                }
                res = CheckStartState();
                if (res)
                {
                    return;
                }
                string? data = args;
                if (data is not null)
                {
                    if (data == "Operation")
                    {
                        InvokeOnUIThread(() =>
                        {
                            OperationForm frm = new OperationForm();
                            frm.Show(this);
                        });
                    }
                    else if (data == "Project")
                    {
                        InvokeOnUIThread(() =>
                        {
                            ProjectSelectForm frm = new ProjectSelectForm();
                            frm.formium = this;
                            frm.Show(this);
                        });
                    }
                }
            });

            RegisterJavaScriptMessagHandler("FormState", args =>
            {
                string? data = args;
                if (data is not null)
                {
                    if (data == "minimize")
                    {
                        InvokeOnUIThread(() =>
                        {
                            WindowState = FormiumWindowState.Minimized;
                        });                }
                    else if (data == "close")
                    {
                        InvokeOnUIThread(() =>
                        {
                            Stop();
                            Thread.Sleep(100);
                            Close();
                        });
                    }
                }
            });

            RegisterJavaScriptMessagHandler("Collect", args =>
            {
                string? data = args;
                if (data is not null)
                {
                    if (data == "start")
                    {
                        bool res = CheckDataBaseState();
                        if (!res)
                        {
                            return;
                        }
                        if (ProjectItemService is not null)
                        {
                            Start();
                        }
                        else
                        {
                            LayerError("请选择试压工程");
                        }
                    }
                    else if (data == "stop")
                    {
                        Stop();
                    }
                }
            });

            RegisterJavaScriptMessagHandler("Report", args =>
            {
                string? data = args;
                if (data is not null)
                {
                    InvokeOnUIThread(() =>
                    {
                        ReportFormium frm = new ReportFormium();
                        frm.TemplateModelServices = TemplateModelService;
                        frm.ProjectItemServices = ProjectItemService;
                        frm.TestRecordModels = TestRecordModelService;
                        frm.ImageData = data;
                        frm.ShowDialog(this);
                    });
                }
            });
        }

        /// <summary>
        /// 开始
        /// </summary>
        private void Start()
        {
            Broad.Broadcast("开始升压，请注意安全");
            SendMessage("开始升压");
            int result = AddTestRecord();
            if (result > 0)
            {
                if (StageList.Count == 0)
                {
                    LayerError("当前工程无试压阶段");
                    return;
                }
                UpdateStartStageInfo(StageList[0]);
                TotalTimer.Start();
                StartTime = TestRecordModelService.Start_time;
                string data = string.Format("startCollect()");
                EvaluateJavaScript(data);

                MainCollectTimer.Start();
                RemoteCollectTimer.Start();

                BroadErrorTimer.Start();
                StartStageTimer.Start();
                StageTimer.Start();
                EvaluateJavaScript("updateChart()");
            }
            else
            {
                LayerError("请重新开始");
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        private void Stop()
        {
            TotalTimer.Stop();
            EndTime = StartTime.AddSeconds(TotalTime);
            UpdateTestRecord();
            TotalTime = 0;
            string data = string.Format("stopCollect()");
            EvaluateJavaScript(data);

            MainCollectTimer.Stop();
            RemoteCollectTimer.Stop();
            BroadErrorTimer.Stop();
            StartStageTimer.Stop();
            StageTimer.Stop();
        }

        private void SendMessage(string msg) 
        {
            string js = string.Format("addMessage('{0}')",msg);
            EvaluateJavaScript(js);
        }

        /// <summary>
        /// 添加试压记录
        /// </summary>
        private int AddTestRecord()
        {
            TestRecordModelService.Number = DateTimeOffset.Now.ToUnixTimeSeconds();
            TestRecordModelService.Start_time = DateTime.Now;
            if (ProjectItemService is not null)
            {
                TestRecordModelService.Project_id = ProjectItemService.ID;
            }
            List<TestRecordModel> list = new List<TestRecordModel>();
            list.Add(TestRecordModelService);
            int result = SqlSugarHelper.Insertable(list);
            return result;
        }

        /// <summary>
        /// 更新试压记录
        /// </summary>
        private int UpdateTestRecord()
        {
            TestRecordModelService.End_time = EndTime;
            TestRecordModelService.Total_time = TotalTime;
            List<TestRecordModel> list = new List<TestRecordModel>();
            list.Add(TestRecordModelService);
            int result = SqlSugarHelper.Updateable<TestRecordModel>(list);
            return result;
        }

        /// <summary>
        /// 检查数据库状态
        /// </summary>
        private bool CheckDataBaseState()
        {
            if (!DataBaseState)
            {
                LayerError("数据库连接失败，无法操作");
            }
            return DataBaseState;
        }

        /// <summary>
        /// 检查开始采集状态
        /// </summary>
        private bool CheckStartState()
        {
            if (StartState)
            {
                LayerError("已开始采集，无法操作");
            }
            return StartState;
        }

        /// <summary>
        /// 设置服务
        /// </summary>
        /// <param name="name"></param>
        private void SetupServices()
        {
            Task.Run(() => {
                LayerLoading("加载设备...");
                Broad.Setup();
                Service.Setup();
                LayerLoadingClose();
            });
        }
        /// <summary>刷新工程信息
        /// 
        /// </summary>
        public void ReloadProjectInfo()
        {
            if (ProjectItemService is not null)
            {
                Dictionary<string, Object> where = new Dictionary<string, Object>();
                where["number"] = ProjectItemService.Number;
                List<ProjectModel> list = SqlSugarHelper.Inquireable<ProjectModel>(where);
                if (list.Count == 0)
                {
                    string data = string.Format("【{0}】项目不存在", ProjectItemService.Name);
                    LayerError(data);
                    ProjectItemService = null;
                }
                else
                {
                    where["number"] = ProjectItemService.TemplateID;
                    List<TemplateModel> list2 = SqlSugarHelper.Inquireable<TemplateModel>(where);
                    if (list2.Count == 0)
                    {
                        string data = string.Format("【{0}】编号试压模板不存在", ProjectItemService.TemplateID);
                        LayerError(data);
                        ProjectItemService = null;
                        TemplateModelService = null;
                    }
                    else
                    {
                        string data = string.Format("updateProjectInfo('{0}','{1}')", ProjectItemService.Number, ProjectItemService.Name);
                        EvaluateJavaScriptAsync(data);
                        TemplateModelService = list2[0];
                        ReloadTemplateInfo();
                    }
                }
            }
        }

        /// <summary>刷新模板信息
        /// 
        /// </summary>
        public void ReloadTemplateInfo()
        {
            string state = "****";
            if (TemplateModelService is not null)
            {
                if (TemplateModelService.FirstStagePressure > 0)
                {
                    StageList.Add("first");               
                }
                else
                {
                    state = "---";
                }
                UpdateCurrentStageResult("firstStage", state);

                if (TemplateModelService.SecondStagePressure > 0)
                {
                    StageList.Add("second");
                    state = "****";
                }
                else
                {
                    state = "---";
                }
                UpdateCurrentStageResult("secondStage", state);

                if (TemplateModelService.ThirdStagePressure > 0)
                {
                    StageList.Add("third");
                    if (StartStagePressure == 0)
                    {
                        StartStagePressure = Math.Round(TemplateModelService.ThirdStagePressure, 3);
                    }
                    state = "****";
                }
                else
                {
                    state = "---";
                }
                UpdateCurrentStageResult("thirdStage", state);

                if (TemplateModelService.IntensityStagePressure > 0)
                {
                    StageList.Add("intensity");
                    state = "****";
                }
                else
                {
                    state = "--";
                }
                UpdateCurrentStageResult("intensityStage", state);

                if (TemplateModelService.RigorStagePressure > 0)
                {
                    StageList.Add("rigor");
                    state = "****";
                }
                else
                {
                    state = "--";
                }
                UpdateCurrentStageResult("rigorStage", state);
            }
        }

        /// <summary> 起步阶段
        /// 
        /// </summary>
        private void CheckStartStage(object? sender, System.Timers.ElapsedEventArgs e)
        {
            string stageString = StageString(StageList[0]);
            string log = string.Empty;
            if ((MainPressure > StartStagePressureMax))
            {
                ReStartTimer();
                log = string.Format("当前压力【{0}】>【{1}】的标准", MainPressure, StartStagePressureMax);
            }
            else if ((MainPressure < StartStagePressureMin))
            {
                ReStartTimer();
                log = string.Format("当前压力【{0}】<【{1}】的标准", MainPressure, StartStagePressureMin);
            }
            else if ((MainPressure >= StartStagePressureMin) && (!StartStageHolding) && MainPressure > 0)
            {
                log = string.Format("【{0}】开始稳压【{1}】，范围：【{2}-{3}】", stageString, StartStagePressure, StartStagePressureMin, StartStagePressureMax);
                StartStageHolding = true;
            }
            if (log.Length > 0)
            {
                Log.Debug(log);
            }

            if (StartStageHolding)
            {
                if (StartStageTime == 0)
                {

                    if (PointList.Count == 0)
                    {
                        log = string.Format("【{0}】稳压通过。", stageString);
                        Log.Debug(log);
                    }
                    if (PointList.Count < 10)
                    {
                        PointList.Add(MainPressure);
                        log = string.Format("【{0}】采集点位数量：【{1}】", stageString, PointList.Count);
                        Log.Debug(log);
                    }
                    else
                    {
                        double sum = PointList.Sum();
                        PointList.Clear();
                        if (StageList.Count >= 1)
                        {
                            StartStageTimer.Stop();
                            HoldingStagePressure = Math.Round(sum / 10.0f, 3);
                            UpdateHoldingStageInfo(CurrentStage);
                            EnableHoldingStage = true;
                        }
                    }
                }
                else
                {
                    log = string.Format("【{0}】稳压剩余【{1}】s", stageString, StartStageTime);
                    Log.Debug(log);
                    if ((MainPressure >= StartStagePressureMin) && (MainPressure <= StartStagePressureMax))
                    {
                        StartStageTime--;
                    }
                    else
                    {
                        
                    }
                }
            }
        }

        /// <summary> 保持阶段
        /// 
        /// </summary>
        private void CheckHoldingStage(object? sender, System.Timers.ElapsedEventArgs e)
        {
           
        }

        /// <summary> 当前阶段
        /// 
        /// </summary>
        private void CheckStage(object? sender, System.Timers.ElapsedEventArgs e)
        {
            if (StageTotalTime > 0)
            {
                StageTotalTime--;
                SurplusTotalTimeString = Tool.SecondToHMS(StageTotalTime);
                UpdateCurrentStageInfo();
            }
            else if (StageTotalTime == 0)
            {
                EnableHoldingStage = false;
                StageTimer.Stop();
                StartStageTimer.Stop();
                ReStartTimer();
                string state = "不合格";
                string stage = CurrentStage;
                if (StageResult == true)
                {
                    state = "合格";
                }
                string msg = string.Format("{0}检测{1}，请注意安全", StageString(CurrentStage), state);
                Broad.Broadcast(msg);
                Thread.Sleep(100);
                if (stage == "first")
                {
                    UpdateCurrentStageResult("firstStage", state);
                }
                else if (stage == "second")
                {
                    UpdateCurrentStageResult("secondStage", state);
                }
                else if (stage == "third")
                {
                    UpdateCurrentStageResult("thirdStage", state);
                }
                else if (stage == "intensity")
                {
                    UpdateCurrentStageResult("intensityStage", state);
                }
                else if (stage == "rigor")
                {
                    UpdateCurrentStageResult("rigorStage", state);
                }
                StageResult = false;
                if (StageList.Count > 1)
                {
                    StageList.RemoveAt(0);
                    UpdateStartStageInfo(StageList[0]);
                    StartStageTimer.Start();
                    StageTimer.Start();
                }
                else
                {
                    StageList.RemoveAt(0);
                    Stop();
                }
            }

            if (EnableHoldingStage)
            {
                if (MainPressure > HoldingStagePressureMax | MainPressure < HoldingStagePressureMin)
                {
                    StageResult = false;
                    Log.Error(string.Format("【{0}】,压力异常：【{1}】【{2}-{3}】",StageString(CurrentStage),MainPressure,HoldingStagePressureMin,HoldingStagePressureMax));
                    SendMessage("压力异常");
                    if (HoldStageErrorTimes <= 3)
                    {
                        HoldStageErrorTimes++;
                    }
                    else
                    {
                        EnableHoldingStage = false;
                        ReStartTimer();
                        StartStageTimer.Start();
                    }
                }
                else
                {
                    StageResult = true;
                    Log.Error(string.Format("【{0}】：【{1}】保持剩余：【{2}】", StageString(CurrentStage), MainPressure,SurplusTotalTimeString));
                }
            }
        }

        /// <summary>
        /// 更新当前阶段信息
        /// </summary>
        private void UpdateCurrentStageInfo()
        {
            string stageString = StageString(CurrentStage);
            string js = string.Format("updateCurrentStage('{0}','{1}')", SurplusTotalTimeString, stageString);
            EvaluateJavaScript(js);
        }

        /// <summary>
        /// 更新当前阶段的试压状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="res"></param>
        private void UpdateCurrentStageResult(string id, string res)
        {
            string js = string.Format("updateStage('#{0}','{1}')",id, res);
            EvaluateJavaScript(js);

        }
        /// <summary> 更新起步阶段信息
        /// 
        /// </summary>
        /// <param name="stage"> 阶段</param>
        /// /// <param name="broadcast">是否播报</param>
        private void UpdateStartStageInfo(string stage)
        {
            CurrentStage = stage;

            if (TemplateModelService is not null)
            {
                string stageString = StageString(stage);
                double multiple = 1;
                int tmp = 1;
                int time = 0;
                string unit = string.Empty;
                if (stage == "first")
                {
                    StartStagePressure = TemplateModelService.FirstStagePressure;
                    unit = TemplateModelService.FirstStageTimeUnit;
                    if (TemplateModelService.FirstStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = TemplateModelService.FirstStageTime;
                }
                else if (stage == "second")
                {
                    StartStagePressure = TemplateModelService.SecondStagePressure;
                    unit = TemplateModelService.SecondStageTimeUnit;
                    if (TemplateModelService.SecondStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = TemplateModelService.SecondStageTime;
                }
                else if (stage == "third")
                {
                    StartStagePressure = TemplateModelService.ThirdStagePressure;
                    unit = TemplateModelService.ThirdStageTimeUnit;
                    if (TemplateModelService.ThirdStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = TemplateModelService.ThirdStageTime;
                }
                else if (stage == "intensity")
                {
                    StartStagePressure = TemplateModelService.IntensityStagePressure;
                    unit = TemplateModelService.IntensityStageTimeUnit;
                    if (TemplateModelService.IntensityStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = TemplateModelService.IntensityStageTime;
                }
                else if (stage == "rigor")
                {
                    StartStagePressure = TemplateModelService.RigorStagePressure;
                    unit = TemplateModelService.RigorStageTimeUnit;
                    if (TemplateModelService.RigorStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = TemplateModelService.RigorStageTime;
                }

                StartStagePressureMax = Math.Round(StartStagePressure * (1 + (TemplateModelService.ErrorRange / 100.0f)), 3);
                StartStagePressureMin = Math.Round(StartStagePressure * (1 - (TemplateModelService.ErrorRange / 100.0f)), 3);
                StageTotalTime = (long)(time * tmp * multiple);
                string msg = string.Format("{0}{1}{2}开始倒计时", stageString, time, unit);
                Broad.Broadcast(msg);
                Log.Debug(msg);
                string log = string.Format("【{0}】,起步基准：【{1}】【{2}-{3}】", StageString(CurrentStage), StartStagePressure, StartStagePressureMin, StartStagePressureMax);
                Log.Debug(log);
                SendMessage(string.Format("{0}开始", StageString(CurrentStage)));
            }
        }

        /// <summary> 更新保持阶段信息
        /// 
        /// </summary>
        /// <param name="stage"> 阶段</param>
        private void UpdateHoldingStageInfo(string stage)
        {
            if (TemplateModelService is not null)
            {
                int stage_estimate_way = 0;
                double stage_estime_value = 0;
                if (stage == "first")
                {
                    stage_estimate_way = TemplateModelService.FirstStageEstimateWay;
                    stage_estime_value = TemplateModelService.FirstStageEstimateValue;
                }
                else if (stage == "second")
                {
                    stage_estimate_way = TemplateModelService.SecondStageEstimateWay;
                    stage_estime_value = TemplateModelService.SecondStageEstimateValue;
                }
                else if (stage == "third")
                {
                    stage_estimate_way = TemplateModelService.ThirdStageEstimateWay;
                    stage_estime_value = TemplateModelService.ThirdStageEstimateValue;
                }
                else if (stage == "intensity")
                {
                    stage_estimate_way = TemplateModelService.IntensityStageEstimateWay;
                    stage_estime_value = TemplateModelService.IntensityStageEstimateValue;
                }
                else if (stage == "rigor")
                {
                    stage_estimate_way = TemplateModelService.RigorStageEstimateWay;
                    stage_estime_value = TemplateModelService.RigorStageEstimateValue;
                }

                if (stage_estimate_way == 1)
                {
                    HoldingStagePressureMin = HoldingStagePressure - stage_estime_value;
                    HoldingStagePressureMax = HoldingStagePressure + stage_estime_value;
                }
                else
                {
                    HoldingStagePressureMax = Math.Round(HoldingStagePressure * (1 + (stage_estime_value / 100.0f)), 3);
                    HoldingStagePressureMin = Math.Round(HoldingStagePressure * (1 - (stage_estime_value / 100.0f)), 3);
                }
                string log = string.Format("【{0}】,保持基准：【{1}】【{2}-{3}】",StageString(CurrentStage),HoldingStagePressure,HoldingStagePressureMin,HoldingStagePressureMax);
                Log.Debug(log);
            }
        }

        /// <summary>重置起步计时器
        /// 
        /// </summary>
        private void ReStartTimer()
        {
            StartStageHolding = false;
            StartStageTime = StartStageTimeInterval;
        }

        private string StageString(string stage)
        {
            string stageString = "";
            if (stage == "first")
            {
                stageString = "第一阶段";
            }
            else if (stage == "second")
            {
                stageString = "第二阶段";
            }
            else if (stage == "third")
            {
                stageString = "第三阶段";
            }
            else if (stage == "intensity")
            {
                stageString = "强度实验阶段";
            }
            else if (stage == "rigor")
            {
                stageString = "严密性实验阶段";
            }
            return stageString;
        }

        /// <summary>
        /// 设置定时器
        /// </summary>
        private void SetupTimer()
        {
            TotalTimer = CollectTimer();
            TotalTimer.Elapsed += MainTime;

            MainCollectTimer = CollectTimer();
            MainCollectTimer.Elapsed += ReadMainRegister;

            RemoteCollectTimer = CollectTimer();
            RemoteCollectTimer.Elapsed += ReadRemoteRegister;

            BroadErrorTimer = CollectTimer();
            BroadErrorTimer.Interval = 10 * 1000;
            BroadErrorTimer.Elapsed += BroadError;

            StartStageTimer = CollectTimer();
            StartStageTimer.Elapsed += CheckStartStage;

            HoldingStageTimer = CollectTimer();
            HoldingStageTimer.Elapsed += CheckHoldingStage;

            StageTimer = CollectTimer();
            StageTimer.Elapsed += CheckStage;
        }

        /// <summary>
        /// 计时器
        /// </summary>
        /// <returns></returns>
        private System.Timers.Timer CollectTimer()
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval = 1000;
            timer.AutoReset = true;//是否重复执行
            return timer;
        }

        /// <summary>
        /// 播报错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BroadError(object? sender, System.Timers.ElapsedEventArgs e)
        {
            int sleep = 50;
            if (MainPressureError)
            {
                Broad.Broadcast("近端压力值采集失败");
            }
            Thread.Sleep(sleep);
            if (MainTemplatureError)
            {
                Broad.Broadcast("近端温度值采集失败");
            }
            Thread.Sleep(sleep);
            if (RemotePressureError)
            {
                Broad.Broadcast("远端压力值采集失败");
            }
            Thread.Sleep(sleep);
            if (RemoteTemplatureError)
            {
                Broad.Broadcast("远端温度值采集失败");
            }
        }
        /// <summary>
        /// 读取近端数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReadMainRegister(object? sender, System.Timers.ElapsedEventArgs e)
        {
            int sleep = 50;
            int fan = ReadCoils("MFan", "");
            if (fan != -1)
            {
                if (fan == 1)
                {
                    MainFanState = true;
                }
                else
                {
                    MainFanState = false;
                }
            }

            Thread.Sleep(sleep);
            double machineTemplature = ReadTemplature("MachineTemplature", "");
            if (machineTemplature != -1)
            {
                MainMachineTemplature = Math.Round(machineTemplature, 3);
            }

            Thread.Sleep(sleep);
            double mpressure = ReadPressure("MPressure", "updateMainPressure","M");
            if (mpressure != -1)
            {
                MainPressure = mpressure;
                MainPressureError = false;
            }
            else
            {
                MainPressureError = true;
            }

            Thread.Sleep(sleep);
            bool enviromentTemplatureResult = false;
            double enviromentTemplature = ReadTemplature("MEnviromentTemplature", "0");
            if (enviromentTemplature != -1)
            {
                MainEnviromentTemplature = Math.Round(enviromentTemplature, 3);
                enviromentTemplatureResult = true;
            }

            Thread.Sleep(sleep);
            bool mediumTemplatureResult = false;
            double mediumTemplature = ReadTemplature("MediumTemplature", "0");
            if (mediumTemplature != -1)
            {
                MainMediumTemplature = Math.Round(mediumTemplature, 3);
                mediumTemplatureResult = true;
            }

            MainTemplatureError = !(enviromentTemplatureResult && mediumTemplatureResult);

            Dictionary<string, string> info = new Dictionary<string, string>();
            info["fan"] = fan.ToString();
            info["machineTemplature"] = MainMachineTemplature.ToString();
            info["enviromentTemplature"] = MainEnviromentTemplature.ToString();
            info["mediumTemplature"] = MainMediumTemplature.ToString();
            info["pressure"] = MainPressure.ToString();
            string js = string.Format("updateMainInfo('{0}')", JsonConvert.SerializeObject(info));
            EvaluateJavaScript(js);
        }

        /// <summary>
        /// 读取远端数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReadRemoteRegister(object? sender, System.Timers.ElapsedEventArgs e)
        {
            int sleep = 70;
            
            int fan = ReadCoils("RFan", "");
            if (fan != -1)
            {
                if (fan == 1)
                {
                    RemoteFanState = true;
                }
                else
                {
                    RemoteFanState = false;
                }
            }

            Thread.Sleep(sleep);
            double machineTemplature = ReadTemplature("RMachineTemplature", "");
            if (machineTemplature != -1)
            {
                RemoteTemplatureError = false;
                RemoteMachineTemplature = Math.Round(machineTemplature,3);
            }
            else
            {
                RemoteTemplatureError = true;
            }

            Thread.Sleep(sleep);
            double mpressure = ReadPressure("RPressure", "updateRemotePressure","R");
            if (mpressure != -1)
            {
                RemotePressureError = false;
                RemotePressure = mpressure;
                MainPressure = mpressure;
            }
            else
            {
                RemotePressureError = true;
            }

            Dictionary<string, string> info = new Dictionary<string, string>();
            info["fan"] = "false";
            info["machineTemplature"] = RemoteMachineTemplature.ToString();
            info["pressure"] = mpressure.ToString();
            string js = string.Format("updateRemoteInfo('{0}')", JsonConvert.SerializeObject(info));
            EvaluateJavaScript(js);
        }

        /// <summary>
        /// 累计时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainTime(object? sender, System.Timers.ElapsedEventArgs e)
        {
            TotalTime++;
            string time = Tool.SecondToHMS(TotalTime);
            try
            {
                string data = string.Format("updateTotalTime('{0}')", time);
                EvaluateJavaScriptAsync(data);
            }
            catch (Exception)
            {
            }  
        }

        /// <summary>
        /// 读取压力
        /// </summary>
        private double ReadPressure(string key, string completion, string location)
        {
            Dictionary<string, object>? back = Service.ReadRegisters(key);

            if (back is not null)
            {
                string alarm = "0";
                string log = string.Empty;
                ushort[] shorts = (ushort[])back["data"];
                DevicePointModel model = Service.DevicePointWithKey(key);
                double outMax = model.OutMax;
                double outMin = model.OutMin;
                double rangeMax = model.RangeMax;
                double rangeMin = model.RangeMin;
                double pressure = (shorts[0] - outMin) / (outMax - outMin);
                pressure = Math.Round(pressure * (rangeMax - rangeMin) + rangeMin, 3);
                if (model.Amend > 0)
                {
                    pressure = Math.Round(pressure * model.Amend, 3);
                }
                if (model.AlarmMax > 0 && pressure > model.AlarmMax)
                {
                    alarm = "1";
                    log = string.Format("【{0}:】【{1}】超过限高阈值【{2}】", model.Name, pressure, model.AlarmMax);
                }
                else if (model.AlarmMin > 0 && pressure < model.AlarmMin)
                {
                    alarm = "1";
                    log = string.Format("【{0}:】【{1}】低于最低阈值【{2}】", model.Name, pressure, model.AlarmMin);
                }
                else
                {
                    alarm = "0";
                    log = string.Format("【{0}:】【{1}】", model.Name, pressure);
                }
                Log.Debug(log);
                if (completion.Length > 0)
                {
                    string js = string.Format("{0}('{1}','{2}')", completion, pressure, alarm);
                    EvaluateJavaScript(js);
                }
                return pressure;
            }
            else
            {
                Log.Error(string.Format("【{0}】读取失败", key));
                return -1;
            }
        }

        /// <summary>
        /// 读取温度
        /// </summary>
        private double ReadTemplature(string key, string completion)
        {
            Dictionary<string, object>? back = Service.ReadRegisters(key);

            if (back is not null)
            {
                string alarm = "0";
                string log = string.Empty;
                ushort[] shorts = (ushort[])back["data"];
                DevicePointModel model = Service.DevicePointWithKey(key);
                float temperature = (Tool.ConvertUshort(shorts[0]) / 10.0f);
                double backTemperature = Math.Round(temperature, 3);
                if (model.Amend > 0)
                {
                    backTemperature = Math.Round(backTemperature * model.Amend, 3);
                }
                if (model.AlarmMax > 0 && backTemperature > model.AlarmMax)
                {
                    alarm = "1";
                    log = string.Format("【{0}:】【{1}】超过限高阈值【{2}】", model.Name, backTemperature, model.AlarmMax);
                }
                else if (model.AlarmMin > 0 && backTemperature < model.AlarmMin)
                {
                    alarm = "1";
                    log = string.Format("【{0}:】【{1}】低于最低阈值【{2}】", model.Name, backTemperature, model.AlarmMin);
                }
                else
                {
                    alarm = "0";
                    log = string.Format("【{0}:】【{1}】", model.Name, backTemperature);
                }
                Log.Debug(log);
                return temperature;
            }
            else
            {
                Log.Error(string.Format("【{0}】读取失败", key));
                return -1;
            }
        }

        /// <summary>
        /// 读取线圈
        /// </summary>
        private int ReadCoils(string key, string completion)
        {
            Dictionary<string, object>? back = Service.ReadRegisters(key);

            if (back is not null)
            {
                string log = string.Empty;
                bool[] shorts = (bool[])back["data"];
                DevicePointModel model = Service.DevicePointWithKey(key);
                bool res = shorts[0];
                Log.Debug(string.Format("【{0}:】【{1}】", model.Name, shorts[0]));
                if (res)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }
            }
            else
            {
                Log.Error(string.Format("【{0}】读取失败", key));
                return -1;
            }
        }
        #endregion

        #region 系统方法

        public IndexFormium()
        {
            ///不显示窗体过度动画
            EnableSplashScreen = false;
            Icon icon = new Icon("logo.ico");
            Icon = icon;
            Sizable = false;//禁止调整窗口大小
            Url = "http://dataqcquisition.app.local/Index.html";
            Loaded += IndexFormium_Loaded;
            PageLoadEnd += IndexFormium_PageLoadEnd;
            RegisterJavaScriptMessagHandler();
        }
        protected override FormStyle ConfigureWindowStyle(WindowStyleBuilder builder)
        {
            var style = builder.UseSystemForm();
            style.TitleBar = false;
            style.DefaultAppTitle = "数据采集";
            style.Maximizable = true;
            style.WindowState = FormiumWindowState.Maximized;
            style.StartCentered = StartCenteredMode.CenterScreen;
            style.ColorMode = FormiumColorMode.Light;
           
            if (Screen.PrimaryScreen is not null)
            {
                style.MinimumSize = Screen.PrimaryScreen.WorkingArea.Size;
            }
            return style;
        }

        /// <summary>窗体加载完成
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IndexFormium_Loaded(object? sender, BrowserEventArgs e)
        {

        }

        /// <summary>页面加载完成
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IndexFormium_PageLoadEnd(object? sender, PageLoadEndEventArgs e)
        {
            LayerLoading("连接数据库...");
            Task.Run(() => {
                int res = 0;
                if (SqlSugarHelper.State() == false)
                {
                    LayerError("连接数据库失败");
                    DataBaseState = false;
                }
                else
                {
                    LayerLoadingClose();
                    DataBaseState = true;
                    res = 1;
                    SetupServices();
                    SetupTimer();
                }
                string data = string.Format("setDataBaseState('{0}')", res);
                EvaluateJavaScript(data);
            });
        }
        #endregion
    }
}
